home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / amok_lha / amok03.lha / IntuiStruct1.3 / IntuiStruct.doc < prev    next >
Text File  |  1993-08-15  |  17KB  |  382 lines

  1. ----------------------------------------------------------------------
  2. Dokumentation zu "IntuiStruct" Version 1.3
  3. Autor: Nicolas Benezan, Postwiesenstr. 2, D7000 Stuttgart 60
  4. ----------------------------------------------------------------------
  5. [Fals Sie diesen Text ausdrucken wollen: es existiert ein Textcraft-
  6. File "Doc.textcraft" mit "mehr Format". Achtung: meine Textcraft-
  7. Version beherrscht keine geschweiften Klammern "{}"! (wenn ich den
  8. #%@!*-Programmierer erwische... ).]
  9.  
  10. Vorwort
  11. -------
  12. Dieses Modul entstand an dem Tag, an dem ich bemerkte, daß mein
  13. Listing bereits ca. 500 Zeilen lang war, und ich erst ein Window mit
  14. einem Menu und einigen Gadgets programmiert hatte...
  15. Es beinhaltet schon oft Dagewesenes (Hilfen zum Öffnen von Screens und
  16. Windows) aber auch Interessantes und Neues (Elegante Unterstützung von
  17. Images, Gadgets und Menus).
  18.  
  19. Neu: Version 1.3
  20. ----------------
  21. Diese Version enthält zusätzlich Routinen zum Erzeugen von Borders und
  22. Requesters. Außerdem kann man seine eigene AllocMem-Prozedur angeben
  23. (Version <1.1 benutzte immer nur Heap).
  24. Beachten Sie bitte auch die Änderungen dieser Dokumentation. Es wurden
  25. einige mißverständliche Stellen verbessert.
  26.  
  27. Copyright-Hinweise
  28. ------------------
  29. "IntuiStruct" ist Public Domain Software, dh. jeder darf es umsonst
  30. benutzen und sooft und für wen er will kopieren. Bedingung ist
  31. allerdings, daß die Kopierhinweise (CopyInfo) beachtet werden. Lesen
  32. Sie bitte das in diesem Verzeichnis befindliche ReadMe-File.
  33.  
  34. Screens, Windows, Text, Gadgets
  35. -------------------------------
  36. Die folgenden Prozeduren sind (fast) selbsterklärend: Die Felder des
  37. entsprechenden RECORDs werden auf die übergebenen Parameter gesetzt
  38. (die Namen der Parameter sind meist gleich oder ähnlich derjenigen des
  39. Intuition-DEFINITION-MODULEs). Es werden immer alle Felder belegt,
  40. auch wenn die Prozedur weniger Parameter hat. Die Default-Werte dieser
  41. automatisch initialisierten Felder werden bei der folgenden
  42. Beschreibung angegeben.
  43.  
  44. StructScreen(NewScreen, depth, detailPen, blockPen, viewModes, type,
  45. defaultTitle);
  46. öffnet den Screen noch nicht sondern übergibt nur die NewScreen-
  47. Struktur, sodaß vor OpenScreen() noch Werte verändert werden können.
  48. Nicht verlangte Parameter werden folgendermaßen initialisiert:
  49. leftEdge:=0;topEdge:=0;height:=stdScreenHeight;
  50. font:=NIL;gadgets:=NIL;customBitmap:=NIL;
  51. IF hires IN ViewModes THEN width:=640 ELSE width:=320 END
  52.  
  53. StructWindow(NewWindow, leftEdge, topEdgr, width, height, detailPen,
  54. blockPen, idcmpFlags, flags, title, screen, type);
  55. öffnet das Window noch nicht sondern übergibt nur die NewWindow-
  56. Struktur, sodaß vor OpenWindow() noch Werte verändert werden können.
  57. Nicht verlangte Parameter werden folgendermaßen initialisiert:
  58. firstGadget:=NIL;checkMark:=NIL;bitMap:=NIL;minWidth:=0;
  59. minHeight:=0;maxWidth:=0;maxHeight:=0
  60.  
  61. StructText(IntuiText, frontPen, backPen, drawMode, leftEdge, topEdge,
  62. iText, nextText);
  63. initialisiert eine IntuiText-Struktur, nicht angegebene Werte:
  64. iTextFont:=NIL
  65.  
  66. StructGadget(Gadget, leftEdge, topEdge, width, height, flags,
  67. activation, gadgetType, gadgetRender, gadgetText, mutualExclude,
  68. gadgetID, nextGadget);
  69. initialisiert eine Gadget-Struktur, nicht angegeben Werte:
  70. selectRender:=NIL;specialInfo:=NIL;userData:=NIL;
  71. "mutualExclude" siehe Abschnitt weiter unten.
  72. StructProp(PropInfo, flags, horizPot, vertPot, horizBody, vertBody);
  73. initialisiert eine PropInfo-Struktur, die mit
  74. Gadget.specialInfo:=ADR(PropInfo)
  75. an das Gadget geknüpft werden kann. Sonstige Parameter:
  76. keine (werden nur von Intuition selbst verwendet)
  77.  
  78. StructString(StringInfo, Buffer(*ARRAY OF CHAR!*), UndoBuffer(*ARRAY
  79. OF CHAR!*));
  80. initialisiert die StringInfo-Struktur folgendermaßen:
  81. buffer:=ADR(Buffer);undoBuffer:=ADR(UndoBuffer);bufferPos:=0;
  82. maxChars:=HIGH(Buffer);dispPos:=0;
  83. alle anderen Felder werden nicht initialisiert.
  84. Verknüpfung mit der Gadget-Struktur siehe StructProp.
  85. Mit "StructString" kann auch ein Integergadget erzeugt werden, wenn
  86. zusätzlich das longint-Flag der Gadget-Struktur gesetzt und das
  87. longInt-Feld der StringInfo initialisiert wird.
  88.  
  89. Mutual exclusion - gegenseitiger Ausschluß von Gadgets
  90. ------------------------------------------------------
  91. Damit ist gemeint, daß beim Anklicken eines bestimmten Gadgets
  92. automatisch andere abgeschaltet werden (was man bei Attribut-Items von
  93. Menus schon gewohnt ist). Im Intuition Reference Manual steht, diese
  94. Funktion sei noch nicht implementiert aber bereits vorgesehen. Sie
  95. werde in einer zukünftigen Version von Intuition verfügbar sein. Wer
  96. es aufgegeben hat, darauf zu warten, wird sich über die Prozedur
  97.  
  98. ExcludeGadget(Gadgets, Window, Requester, Mask)
  99.  
  100. freuen. Man ruft sie mit folgenden Parametern auf, nachdem man erkannt
  101. hat, daß ein Gadget, das andere ausschließen soll, aktiviert wurde.
  102.  
  103. Gadgets: Zeiger auf das erste User(!)-Gadget des Windows oder
  104. Requesters. Vorsicht: nicht den Zeiger Window.firstGadget verwenden!
  105. Er zeigt auf das erste System-Gadget des Windows.
  106. Window: Zeiger auf das Window, in dem sich das Gadget befindet
  107. Requester: Zeiger auf den Requester, falls es sich um das Gadget eines
  108. Requesters handelt, ansonsten NIL
  109. Mask: Maske der auszuschließenden Gadgets (gesetztes Bit=ausschließen,
  110. gelöschtes=unverändert lassen). Bit 0 steht für das erste Gadget in der verketteten Liste der User-Gadgets, Bit 1 für das zweite usw.
  111. Natürlich ist "mutual exclusion" nur bei toggleSelect-Gadgets
  112. sinnvoll, wenig Sinn haben auch Gadgets, die sich selbst ausschließen.
  113. Am besten wird die Maske im dafür vorgesehenen Feld der
  114. Gadget-Struktur abgelegt. Der Aufruf lautet dann etwa:
  115.  
  116. ExcludeGadget(GadgetStripPtr, MeinWindow, NIL,
  117.         aktivesGadget.mutualExclude);
  118.  
  119. Entgegen der sonst üblichen Methode wird nicht RefreshGadgets(
  120. GadgetStripPtr,...) aufgerufen, was alle Gadgets neu zeichnet. Nur die
  121. betroffenen Gadgets werden neu gezeichnet. Dies verhindert das sonst,
  122. besonders bei sehr vielen Gadgets pro Window, zu beobachtende "Zucken"
  123. beim Anklicken eines Gadgets.
  124.  
  125. Neu: Requester
  126. --------------
  127. StructRequest(Requester, leftEdge, topEdge, width, height, reqGadget,
  128. reqBorder, reqText, backFill);
  129. initialisiert eine Requesterstruktur. Defaultwerte:
  130. flags:=RequesterFlagSet{};
  131.  
  132. Images elegant erzeugt
  133. ----------------------
  134. Jetzt ist Schluß mit dem Ärger mit Hexadezimalen Zahlen, mit
  135. umständlicher Erzeugung der Image-Struktur und mit der Ungewißheit, ob
  136. die Bitplanes jetzt wirklich im ChipMem liegen. Hier ein Beispiel mit
  137. StructImage:
  138.  
  139. StructImage(Smily,X,Y,24,18,1(*depth*),{0,1}(*PlanePick*),
  140.         {}(*PlaneOnOff*),NIL(*nextImage*));
  141. Long(000000001111111100000000L);
  142. Long(000001110000000011100000L);
  143. Long(000110000000000000011000L);
  144. Long(001000000000000000000100L);
  145. Long(010000110000000011000010L);
  146. Long(010000110000000011000010L);
  147. Long(100000000000000000000001L);
  148. Long(100000000000000000000001L);
  149. Long(100000000000000000000001L);
  150. Long(100001100000000001100001L);
  151. Long(010000011100001110000010L);
  152. Long(010000000011110000000010L);
  153. Long(001000000000000000000100L);
  154. Long(000110000000000000011000L);
  155. Long(000001110000000011100000L);
  156. Long(000000001111111100000000L);
  157. ImageEnd;
  158.  
  159. ChipMem für die Bitplane(s) wird automatisch alloziert und bei
  160. Programmbeendigung freigegeben, ohne daß man sich darum kümmern muß.
  161. Nach ImageEnd ist das Image zur Verwendung bereit.
  162. Man muß lediglich darauf achten, daß die Anzahl der Long() bzw Word()
  163. Aufrufe mit der Anzahl der für die Image-Bitplane(s) benötigten
  164. (Lang-)Wort übereinstimmt. Sonst wird mit einer Fehlermeldung
  165. abgebrochen.
  166. Besteht das Image aus mehreren Bitplanes, so werden diese einfach nacheinander mit Word() oder Long() angeführt. Hätte obiges Beispiel 2
  167. Bitplanes so kämen also nach den ersten 18 Long()s nocheinmal 18 für
  168. die zweite Bitplane.
  169. Ist das Image breiter als 32 Bit, dann stehen in einer Zeile mehrere Long()s und Word()s. Beachten Sie, daß Sie immer ein Vielfaches von 16
  170. Bits angeben müssen, z.B. für ein 40 Pixel breites Image:
  171. Long(11000101011101010001100001101001L);Word(1001110100000000L);
  172. Die letzten 8 Bits haben keine Bedeutung mehr, müssen aber angeführt
  173. werden.
  174.  
  175. Neu: mit FreeImage(Image) kann das belegte Chip-Ram (Image.imageData)
  176. wieder freigegeben werden.
  177.  
  178. Neu: Borders
  179. ------------
  180. Ähnlich wie Images werden auch die Border Strukturen erzeugt. Die
  181. Anweisungen StructBorder und BorderEnd umschließen die Definition der
  182. Border-Linien.
  183.  
  184. StructBorder(Border, leftEdge, topEdge, frontPen, drawMode, NumLines,
  185. nextBorder);
  186. initialisiert eine Borderstruktur und bereitet IntuiStruct auf
  187. folgende Aufrufe von AddLine, Rectangle und BorderEnd vor. Default:
  188. backPen:=0;
  189. Beachten Sie, daß der Parameter NumLines nicht dem Feld Border.count
  190. entspricht. NumLines ist die Anzahl der Linien, nicht die der
  191. Eckpunkte.
  192.  
  193. Nach StructBorder gibt es zwei Möglichkeiten. Entweder folgen Numlines
  194. Aufrufe von AddLine oder ein (und nur ein) Aufruf von Rectangle.
  195. AddLine fügt jeweils eine Linie an die Borderstruktur an. Es müssen
  196. insgesammt genau soviele AddLines sein, wie mit NumLines angegeben
  197. wurden.
  198. Rectangle fügt gleich vier Linien auf einmal an, logischerweise ein
  199. geschlossenes Rechteck. Bei der Breite und Höhe sind die Randlinien
  200. selbst inklusiv, dh. die Eckpunkte sind width-1 bzw. height-1
  201. voneinander entfernt. Pro Borderstruktur darf nur ein Rectangle
  202. definiert werden, und der Wert NumLines muß auf 4 gesetzt werden.
  203. BorderEnd schließt die Definition ab.
  204.  
  205. Mit FreeBorder(Border) kann der unter Border.xy belegte Speicher
  206. wieder freigegeben werden.
  207.  
  208. Menus
  209. -----
  210. Wer einmal ein umfangreiches Menu programmiert hat, der weiß, daß dies
  211. in eine ziemlich große Schreibarbeit ausartet. Erst muß für jeden
  212. Menupunkt (Item) und eventuell für die untergeordneten Punkte
  213. (SubItems) eine IntuiText-Struktur erzeugt werden. Dann wird für jedes
  214. Item und SubItem eine MenuItem-Struktur Initialisiert, die einen
  215. Zeiger auf die zugehörige IntuiText-Struktur enthält. Schließlich
  216. müssen die SubItems untereinander und mit ihrem Item, die Items
  217. untereinander und mit ihrem Menu(-kopf) verbunden werden, und endlich
  218. die Menus zum gesammten MenuStrip zusammengefügt werden.
  219. Mit dem vorliegenden Modul wird diese Prozedur enorm vereinfacht.
  220.  
  221. SubItem(ADR(Name), leftEdge, width, flags, mutualExclude, command);
  222. initialisiert eine MenuItem-Struktur (als SubItem) und die
  223. zugehörige IntuiText-Struktur. Parameter:
  224. leftEdge: Position des linken Rands der Selectbox des Subitems
  225. relativ zum linken Rand des Items, unter dem diese(s) SubItem
  226. steht/stehen
  227. width: Breite der Selectbox
  228. flags: MenuItemFlags (itemText muß gesetzt sein)
  229. mutualExclude: Ausschluß anderer Attributitems (Bit 0 für das
  230. oberste, also das zuletzt erzeugte SubItem)
  231. command: eventueller "Menuersatz-Key" (+rechte Amigataste), nur erforderlich, wenn das commSeq-Flag gesetzt ist
  232.  
  233. Alle anderen Felder werden später automatisch initialisiert (siehe
  234. LinkMenu). Die IntuiText-Struktur wird beim Aufruf von SubItem so
  235. initialisiert:
  236. frontPen:=0;backPen:=1;drawMode:=jam1;leftEdge:=0;topEdge:=0;
  237. iTextFont:=NIL;iText:=ADR(Name);nextText:=NIL;
  238. Wurde vorher (bzw. seit dem letzten Item-Aufruf) schon einmal SubItem
  239. aufgerufen, so wird das zuletzt definierte SubItem als nextItem in das
  240. gerade definierte SubItem eingetragen. Das bedeutet, wenn mehrmals
  241. hintereinander SubItem aufgerufen wird, sind die SubItems bereits von
  242. selbst miteinander verbunden. Das zuletzt definierte steht dabei als
  243. oberstes SubItem.
  244.  
  245. Das erzeugen von Items läuft fast genauso ab:
  246.  
  247. Item(ADR(Name), width, flags, mutualExclude, command);
  248. initialisiert eine MenuItem-Struktur und die zugehörige
  249. IntuiText-Struktur. Es muß hier kein leftEdge angegeben werden, da
  250. alle Items immer genau unter dem Menutitel stehen. Wurde seit dem
  251. letzten Item Aufruf ein oder mehrere male SubItem aufgerufen, so
  252. werden alle diese SubItems automatisch mit dem neuen Item verbunden.
  253. Ebenso sind alle seit dem letzten LinkMenu-Aufruf erzeugten Items
  254. mit diesem Item verbunden.
  255.  
  256. Sind alle Items und SubItems einer Menuspalte erzeugt, wird LinkMenu
  257. aufgerufen:
  258.  
  259. status:=LinkMenu(MenuStripPtr,Name,leftEdge,width,enabled);
  260.  
  261. erzeugt eine Menu-Struktur und bindet diese an erster Stelle in den
  262. MenuStrip ein. Falls dies der erste Aufruf ist, sollte der
  263. MenuStrip-Pointer gleich NIL sein. LeftEdge und width beschreiben
  264. die Position und Größe der Menu-Selectbox in der Screen-Titelleiste.
  265. Enabled besagt, ob diese Menuspalte anwählbar (TRUE) oder gesperrt
  266. (FALSE) sein soll. Mit dem LinkMenu-Aufruf werden auch die
  267. Positionen aller Items und SubItems berechnet und in die
  268. MenuItem-Strukturen eingetragen. Das zuletzt definierte Item steht
  269. dabei direkt unter der Titelleiste, das vorletzte Item "StdHeight"
  270. Pixel darunter usw. Das erste (zuletzt definierte) SubItem eines
  271. Items steht direkt neben dem Item, alle nachfolgenden (vorher
  272. definierten) stehen "StdHeight" tiefer usw. Hat ein (Sub)Item das
  273. checkIt- oder das commSeq-Flag gesetzt, wird automatisch links
  274. seines Namens CheckWidth Pixel bzw. rechts CommWidth Pixel Platz
  275. reserviert.
  276. Ist status=TRUE, dann konnte das Menu korrekt erzeugt werden, ist es
  277. FALSE, dann trat ein Fehler auf. Es kann beispielsweise sein, daß
  278. für eine Item-Struktur kein Speicher mehr frei war. Falls ein neuer
  279. Versuch stattfinden soll, muß wieder mit dem untersten (Sub-)Item
  280. begonnen werden.
  281.  
  282. Es wird empfohlen, Speichermangel mit Hilfe des AllocProc-
  283. Mechanismus abzufangen (siehe dort), da wenn status=FALSE ist,
  284. es für einen Teil des Speichers bereits "zu spät" ist. In der
  285. vorliegenden Version ist es möglich, das bei einem mißlungenen
  286. Versuch Speicher blockiert wird, der erst wieder bei Verlassen des
  287. Programms frei wird.
  288.  
  289. Es sei noch einmal erwähnt, daß die Items in umgekehrter Reihenfolge
  290. definiert werden müssen, wie sie später im Menu erscheinen sollen. Das
  291. zuletzt definierte Item steht an berster Stelle und hat die "ItemNum"-
  292. mer 0, das zuvor definierte steht darunter und hat die Nummer 1 usw.
  293. Am besten zeigt dies ein Beispiel. Es soll folgendes Menu programmiert
  294. werden:
  295.  
  296. Commands                Attributes
  297. --------                ----------
  298. do nothing              magic
  299. do less                 more magic
  300. do something -  this
  301.                 that
  302.  
  303.  
  304.  
  305.  
  306. In Modula mit Hilfe von IntuiStruct sieht das dann so aus:
  307.  
  308. MenuStripPtr:=NIL;
  309. Item(ADR("more magic"), 80, MenuItemFlagSet{checkIt, itemText,
  310.   itemEnabled, highComp, checked}, LONGSET{0}, ASCII.nul);
  311. Item(ADR("magic"), 80, MenuItemFlagSet{checkIt, itemText,
  312.   itemEnabled, highComp}, LONGSET{1}, ASCII.nul);
  313. LinkMenu(MenuStripPtr, ADR("Attributes"), 240, 80, TRUE);
  314.  
  315. SubItem(ADR("that"), 64, 32, MenuItemFlagSet{itemText,
  316.   itemEnabled, highComp}, LONGSET{}, ASCII.nul);
  317. SubItem(ADR("this"), 64, 32, MenuItemFlagSet{itemText,
  318.   itemEnabled, highComp}, LONGSET{}, ASCII.nul);
  319. Item(ADR("do something"), 96, MenuItemFlagSet{itemText,
  320.   itemEnabled, highComp}, LONGSET{}, ASCII.nul);
  321. Item(ADR("do less"), 96, MenuItemFlagSet{itemText,
  322.   itemEnabled, highComp}, LONGSET{}, ASCII.nul);
  323. Item(ADR("do nothing"), 96, MenuItemFlagSet{itemText,
  324.   itemEnabled, highComp}, LONGSET{}, ASCII.nul);
  325. LinkMenu(MenuStripPtr, ADR("Commands"), 0, 64
  326. , TRUE);
  327.  
  328. Nach öffnen des Windows braucht man nur noch SetMenuStrip(WindowPtr,
  329. MenuStripPtr) auszuführen.
  330.  
  331. Neu: mit der Prozedur UnlinkMenu(MenuStrip) kann der von einem ganzen
  332. MenuStrip belegte Speicher wieder freigegeben werden. Es wird das
  333. Menu, dessen Zeiger übergeben wurde, alle folgenden Menus, alle Items
  334. und SubItems dealloziert. Soll eine einzelne Menuspalte dealloziert
  335. werden, muß sie vorher aus dem MenuStrip entfernt werden, ihr
  336. nextMenu-Feld muß in diesem Fall auf NIL stehen.
  337.  
  338. MenuNumbers
  339. -----------
  340. Leider sin die Funktionen MENUNUM, ITEMNUM und SUBNUM (siehe Intuition
  341. Reference Manual S. 126/127) im M2Amiga Modul Intuition nicht
  342. Implementiert. In IntuiStruct ist dies nachgeholt. Dazu gehören
  343. auch die Konstanten MenuNull, NoItem und NoSub. Nützlich ist auch die
  344.  Funktion MakeNum, wenn man zB. die Adresse eines bestimmten
  345. Items haben will, denn diese wird ja von IntuiStruct bei deren
  346. Definition geheimgehalten. MakeNum Ist gewissermaßen die Umkehrung von
  347. MenuNum, ItemNum und SubNum. Beispiel:
  348.  
  349. ItemAdr:=ItemAddress(MenuStripPtr,MakeNum(MenuNum,ItemNum,SubNum));
  350.  
  351. Neu: AllocProc, DeallocProc
  352. ---------------------------
  353. Version 1.0 von IntuiStruct verwendete immer das Bibliotheksmodul Heap
  354. für seine Speicherverwaltung. Um eine andere Speicherverwaltung
  355. verwenden zu können, wurden die Prozedurvariablen AllocProc und
  356. DeallocProc eingeführt. Als Beispiel sei hier "MemSystem" [bne]
  357. genannt, das demnächst auf einer Amok-Diskette erscheint und wirklich
  358. Interessantes zu bieten hat.
  359. Bevor sie eine der Prozeduren
  360.         StructImage,
  361.         LinkMenu, Item, SubItem,
  362.         StructBorder
  363. benutzen, müssen die oben genannten Prozedurvariablen auf eine gültige
  364. AllocMem- und Deallocate-Prozedur gestellt werden.
  365. Vorsicht: diese Liste gilt nur für Version 1.3 und ältere.
  366. Um wenigstens einigermaßen kompatibel zu bleiben, wurden die gleichen
  367. Prozedurtypen wie in Heap verwendet (AllocProcType, DeallocProcType).
  368. Die Konstanten CHIP und CHIPorFAST erklären sich wohl selbst.
  369.  
  370. Beispiel:
  371. IntuiStruct.AllocProc:=Heap.AllocMem;
  372. IntuiStruct.DeallocProc:=Heap.Deallocate;
  373.  
  374. oder:
  375. IntuiStruct.AllocProc:=MemSystem.AllocMem;
  376. IntuiStruct.DeallocProc:=MemSystem.Deallocate;
  377.  
  378. _____________________
  379.  
  380. Viel Spaß !
  381.   Bene
  382.